﻿using TrackSystem.IO.Data;
using TrackSystem.IO.Formula;
using TrackSystem.IO.Models;

namespace TrackSystem.IO.Sensors
{
    public class SensorUnit
    {
        /// <summary>
        /// 传感器名称
        /// </summary>
        public string? Name { get; set; }
        /// <summary>
        /// 传感器描述
        /// </summary>
        public string? Description { get; set; }
        /// <summary>
        /// 发送缓冲区
        /// </summary>
        public byte[] Tx_r { get; set; }
        /// <summary>
        /// 接收缓冲区
        /// </summary>
        public byte[] Rx_r { get; set; }
        /// <summary>
        /// 发送缓冲区
        /// </summary>
        public byte[] Tx_w { get; set; }
        /// <summary>
        /// 接收缓冲区
        /// </summary>
        public byte[] Rx_w { get; set; }
        /// <summary>
        /// 读操作通信成功计数器
        /// </summary>
        public int Succ_R { get; set; }
        /// <summary>
        /// 读操作通信失败计数器
        /// </summary>
        public int Fail_R { get; set; }
        /// <summary>
        /// 写操作通信成功计数器
        /// </summary>
        public int Succ_W { get; set; }
        /// <summary>
        /// 写操作通信失败计数器
        /// </summary>
        public int Fail_W { get; set; }
        /// <summary>
        /// 通信使能标记
        /// </summary>
        public bool Enabled { get; set; }
        /// <summary>
        /// 通信间隔, 单位ms
        /// </summary>
        public int Interval { get; set; }
        /// <summary>
        /// 通信时间花费时间
        /// </summary>
        public int Lapse { get; set; }
        /// <summary>
        /// 写入队列的长度
        /// </summary>
        public int QueueLen { get; set; }

        /// <summary>
        /// 只读寄存器名称
        /// </summary>
        public Dictionary<string, OperandDef>? roRegs { get; set; }
        /// <summary>
        /// 读写寄存器名称
        /// </summary>
        public Dictionary<string, OperandDef>? rwRegs { get; set; }
    }

    /// <summary>
    /// 实用方法
    /// </summary>
    public static class SensorUtils
    {
        public static SensorUnit ConvertUnit(this ProtocolBase sensor)
        {
            var unit = new SensorUnit();
            unit.Name = sensor.Name;
            unit.Tx_r = sensor.Tx_r;
            unit.Rx_r = sensor.Rx_r;
            unit.Tx_w = sensor.Tx_w;
            unit.Rx_w = sensor.Rx_w;
            unit.Succ_W = sensor.Succ_W;            
            unit.Fail_W = sensor.Fail_W;
            unit.Succ_R = sensor.Succ_R;
            unit.Fail_R = sensor.Fail_R;
            unit.Enabled = sensor.Enabled;
            unit.Interval = sensor.Interval;
            unit.Lapse = sensor.Lapse;
            unit.QueueLen = sensor.QueueLen;
            unit.roRegs = new();
            unit.rwRegs = new();

            var regs = RegFactory.Instance;
            foreach (var regName in sensor.RegNameList)
            {
                if (regs.Attrs.TryGetValue(regName, out var regAttr))
                {
                    if (regAttr.ReadOnly) unit.roRegs.TryAdd(regName, regs[regName]);
                    else unit.rwRegs.TryAdd(regName, regs[regName]);
                }
            }

            return unit;
        }
    }
}
